﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public delegate void EventListenerDelegate(NotifyEvent evt);
public class NotifacitionCenter
{
    private static NotifacitionCenter instance;
    private NotifacitionCenter() { }
    public static NotifacitionCenter GetInstance()
    {
        if (instance == null)
        {
            instance = new NotifacitionCenter();
        }
        return instance;
    }

    // 成员变量  
    Dictionary<string, EventListenerDelegate> notifications = new Dictionary<string, EventListenerDelegate>(); // 所有的消息

    // 注册监视  
    public void registerObserver(string type, EventListenerDelegate listener)
    {
        if (listener == null)
        {
            Debug.LogError("registerObserver: listener不能为空");
            return;
        }

        // 将新来的监听者加入调用链，这样只要调用Combine返回的监听者就会调用所有的监听者  
        //Debug.Log("NotifacitionCenter: 添加监视" + type);

        EventListenerDelegate myListener = null;
        notifications.TryGetValue(type, out myListener);
        notifications[type] = (EventListenerDelegate)Delegate.Combine(myListener, listener);
    }

    // 移除监视  
    public void removeObserver(string type, EventListenerDelegate listener)
    {
        if (listener == null)
        {
            Debug.LogError("removeObserver: listener不能为空");
            return;
        }

        // 与添加的思路相同，只是这里是移除操作  
        Debug.Log("NotifacitionCenter: 移除监视" + type);
        notifications[type] = (EventListenerDelegate)Delegate.Remove(notifications[type], listener);
    }

    public void removeAllObservers()
    {
        notifications.Clear();
    }

    // 消息触发  
    public void postNotification(NotifyEvent evt)
    {
        EventListenerDelegate listenerDelegate;
        if (notifications.TryGetValue(evt.Type, out listenerDelegate))
        {
            try
            {
                // 执行调用所有的监听者  
                listenerDelegate(evt);
            }
            catch (System.Exception e)
            {
                throw new Exception(string.Concat(new string[] { "Error dispatching event", evt.Type.ToString(), ": ", e.Message, " ", e.StackTrace }), e);
            }
        }
    }
}
